package com.pwt.service;

import com.pwt.entity.FilterUnit;
import com.pwt.model.DiagramModel;
import com.pwt.model.TreeModel;
import com.pwt.model.crustallus.FanDiagramModel;
import com.pwt.model.crustallus.GroupModel;
import com.pwt.model.crustallus.OrderModel;
import com.pwt.model.what.OverviewModel;
import com.pwt.repository.*;
import com.pwt.utils.DoubleUtils;
import com.pwt.utils.MathUtil;
import com.pwt.utils.SigmaUtil;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 分析页面
 * @author dw
 * @version 1.0.0
 * @date 2021/10/13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AnalyseService {


    private WERTEVARRepository wertevarRepository;

    private SigmaUtil sigmaUtil;

    private AbilityLineRepository abilityLineRepository;

    private HierarchyRepository hierarchyRepository;

    private PowerModuleRepository powerModuleRepository;

    private FilterUnitRepository filterUnitRepository;

    private JPAQueryFactory jpaQueryFactory;

    private RoleRepository roleRepository;

    private AbilityLineService abilityLineService;

    private CrustalLusService crustalLusService;

    public AnalyseService(WERTEVARRepository wertevarRepository, SigmaUtil sigmaUtil, AbilityLineRepository abilityLineRepository, HierarchyRepository hierarchyRepository, PowerModuleRepository powerModuleRepository, FilterUnitRepository filterUnitRepository, JPAQueryFactory jpaQueryFactory, RoleRepository roleRepository, AbilityLineService abilityLineService, CrustalLusService crustalLusService) {
        this.wertevarRepository = wertevarRepository;
        this.sigmaUtil = sigmaUtil;
        this.abilityLineRepository = abilityLineRepository;
        this.hierarchyRepository = hierarchyRepository;
        this.powerModuleRepository = powerModuleRepository;
        this.filterUnitRepository = filterUnitRepository;
        this.jpaQueryFactory = jpaQueryFactory;
        this.roleRepository = roleRepository;
        this.abilityLineService = abilityLineService;
        this.crustalLusService = crustalLusService;
    }

    /**
     * 查询用户配置 所有产品的 比例
     * @param filterId
     * @param startTime
     * @param endTime
     * @return
     */
    public List<FanDiagramModel> getAnalyseFanDiagramModel(String filterId,String startTime, String endTime){
        String filters = null;
        if(filters != null && !filters.equals("")){
            FilterUnit filter = this.filterUnitRepository.findById(filterId).orElse(null);
            if(filter != null){
                filters = filter.getImportance();
            }
        }

        Set<Integer> machine = new HashSet<>();
        List<TreeModel> treeList = abilityLineService.getHierarchySelect();
        if(treeList != null){
            for (TreeModel tree:treeList) {
                if(tree != null && tree.getChildren() != null && tree.getChildren().size() > 0 ){
                    for (TreeModel twoTree:tree.getChildren()) {
                        machine.add(twoTree.getId());
                    }

                }
            }
        }



//        List<OverviewModel>  characterList= this.wertevarRepository.getCharacteristicsByProcessAndMachine( filters , machine,  null,null, startTime,  endTime);
//
//        if(characterList != null && characterList.size() > 0 ){
//            //被测参数数量
//            groupModel.setCount(characterList.size());
//
//            for (OverviewModel character:characterList) {
//                //根据被测参数 获取 测量值
//                List<Double> values = this.wertevarRepository.getValueByProcessAndMachine(filters,machine,null,null, startTime, endTime);
//                groupModel.setNumberOfParts(groupModel.getNumberOfParts()+values.size());
//                Double avg = 0.00D;
//                for (Double d:values) {
//                    avg = avg+d;
//
//                }
//                avg = avg/values.size();
//
//                Double down = character.getK2110();
//                Double up = character.getK2111();
//                Double sigma = sigmaUtil.getSigma(values,avg);
//                Double T = up - down;
//
//                //cp
//                Double  cp= T/6*sigma;
//                cp = DoubleUtils.retain2(cp);
//                Double cpu = (up - avg) / 3*sigma;
//                cpu = DoubleUtils.retain2(cpu);
//                Double cpl = (avg - down) / 3*sigma;
//                cpl = DoubleUtils.retain2(cpl);
//                //cpk
//                Double cpk = Math.min(cpu,cpl);
//                // 判断状态  产品是否合格
//                if(cp >= character.getCpTarget()
//                        && cpk >= character.getCpkTarget()){
//                    if(values != null && values.size() <= 40 ){
//                        groupModel.setHasQualified(groupModel.getHasQualified()+1);
//                    }else{
//                        groupModel.setQualified(groupModel.getQualified()+1);
//                    }
//                }else{
//                    groupModel.setDisqualification(groupModel.getDisqualification()+1);
//                }
//
//
//            }
//            groupModel.setQualifiedRate(DoubleUtils.retainPercent2((double) (groupModel.getQualified()/groupModel.getCount())));
//            groupModel.setHasQualifiedRate(DoubleUtils.retainPercent2((double) (groupModel.getHasQualified()/groupModel.getCount())));
//            groupModel.setDisqualificationRate(DoubleUtils.retainPercent2((double) (groupModel.getDisqualification()/groupModel.getCount())));
//        }
        DiagramModel groupModel = this.powerModuleRepository.queryByK0010(filters,machine,startTime,endTime);
        //返回扇形图数据
        List<FanDiagramModel> groupList = new ArrayList<>();
        FanDiagramModel  fanDiagramModel = new FanDiagramModel();
        DiagramModel groupModel1 = new DiagramModel(groupModel);
        groupModel1.setName("合格的被测参数");
        fanDiagramModel.setValue(groupModel.getQualifiedRate());
        fanDiagramModel.setGroupModel(groupModel1);
        FanDiagramModel  fanDiagramModel1 = new FanDiagramModel();
        DiagramModel groupModel2 = new DiagramModel(groupModel);
        groupModel2.setName("有条件合格的被测参数");
        fanDiagramModel1.setValue(groupModel.getHasQualifiedRate());
        fanDiagramModel1.setGroupModel(groupModel2);
        FanDiagramModel  fanDiagramModel2 = new FanDiagramModel();
        DiagramModel groupModel3 = new DiagramModel(groupModel);
        groupModel3.setName("不合格合格的被测参数");
        fanDiagramModel2.setValue(groupModel.getDisqualificationRate());
        fanDiagramModel2.setGroupModel(groupModel3);
        groupList.add(fanDiagramModel);groupList.add(fanDiagramModel1);groupList.add(fanDiagramModel2);
        return groupList;
    }


    public  List<FanDiagramModel> getAnalyseProcessDiagramList(String filterId,String startTime, String endTime){
        String filters = null;
        if(filters != null && !filters.equals("")){
            FilterUnit filter = this.filterUnitRepository.findById(filterId).orElse(null);
            if(filter != null){
                filters = filter.getImportance();
            }
        }

        List<TreeModel> treeList = abilityLineService.getHierarchySelect();
        //返回结果
        List<DiagramModel> result = new ArrayList<>();
        if(treeList != null){
            for (TreeModel tree:treeList) {
                Set<Integer> machine = new HashSet<>();
                if(tree != null && tree.getChildren() != null && tree.getChildren().size() > 0 ){
                    for (TreeModel twoTree:tree.getChildren()) {
                        machine.add(twoTree.getId());
                    }
                }
//                GroupModel resultGroup  = this.crustalLusService.selectGroupList(groupModel,filters,machine,null,startTime,endTime);
//                resultGroup.setNumberOfParts(machine.size());
                DiagramModel resultGroup = this.powerModuleRepository.queryByK0010(filters,machine,startTime,endTime);
                if(resultGroup == null || resultGroup.getCount() == null || resultGroup.getCount() == 0) continue;
                resultGroup.setId(tree.getId());
                resultGroup.setName(tree.getName());
                result.add(resultGroup);
            }
        }


        //返回扇形图数据
        List<FanDiagramModel> diagramModelList = new ArrayList<>();
        for (int i = 0; i < result.size(); i++) {
            FanDiagramModel  fanDiagramModel = new FanDiagramModel();
            fanDiagramModel.setValue(result.get(i).getDisqualificationRate());
            fanDiagramModel.setGroupModel(result.get(i));
            diagramModelList.add(fanDiagramModel);
        }
        return diagramModelList;

    }


    public  List<GroupModel> getAnalyseMachineFlowList(String filterId,String processIds,String partIds,String nestIds,String startTime, String endTime){
        String filters = null;
        if(filters != null && !filters.equals("")){
            FilterUnit filter = this.filterUnitRepository.findById(filterId).orElse(null);
            if(filter != null){
                filters = filter.getImportance();
            }
        }

        List<TreeModel> treeList = abilityLineService.getHierarchySelect();
        //机器
        Set<Integer> machine = StringCastMachine(processIds,treeList);

        //零件
        Set<Integer> parts = null;
        if(StringUtils.isNotBlank(partIds)){
            parts = StringCastSet(partIds);
        }
        return this.powerModuleRepository.queryGroupByMaschine(machine,parts,startTime,endTime);

        //巢穴集合
//        Set<Integer> nests = null;
//        if(StringUtils.isNotBlank(nestIds)){
//            nests = StringCastSet(nestIds);
//        }
//        List<GroupModel> result = new ArrayList<>();
//        List<GroupModel> groupList = this.wertevarRepository.getMachineGroupModer(filters,machine,parts,nests,startTime,endTime);
//        for (GroupModel group: groupList) {
//            GroupModel resultGroup  = selectGroupList(group,filters,machine,parts,nestIds,startTime,endTime);
//            result.add(resultGroup);
//        }
//
//        return result;
    }


    public List<GroupModel> getAnalysePart( String filterId,String processIds,String nestIds,String startTime, String endTime){

        String filters = null;
        if(filters != null && !filters.equals("")){
            FilterUnit filter = this.filterUnitRepository.findById(filterId).orElse(null);
            if(filter != null){
                filters = filter.getImportance();
            }
        }

        List<TreeModel> treeList = abilityLineService.getHierarchySelect();

        //机器
        Set<Integer> machine = StringCastMachine(processIds,treeList);

        return this.powerModuleRepository.queryGroupByPart(machine,null,startTime,endTime);
        //巢穴集合
//        Set<Integer> nests = null;
//        if(StringUtils.isNotBlank(nestIds)){
//            nests = StringCastSet(nestIds);
//        }
//        List<GroupModel> result = new ArrayList<>();
//        List<GroupModel> groupList = this.wertevarRepository.getPartGroupModerList(filters,machine,nests,startTime,endTime);
//        for (GroupModel group: groupList) {
//            Set<Integer> partIds = new HashSet<>();
//            partIds.add(group.getId());
//            GroupModel resultGroup  = selectGroupList(group,filters,machine,partIds,nestIds,startTime,endTime);
//            result.add(resultGroup);
//        }
//        return result;

    };



    public GroupModel  selectGroupList(GroupModel group,String filters, Set<Integer> machineIds, Set<Integer> partIds,String nestIds,String startTime, String endTime){
        List<OverviewModel>  characterList= this.wertevarRepository.getCharacteristicsByProcessAndMachine( filters , machineIds,  partIds,nestIds, startTime,  endTime);
        if(characterList != null && characterList.size() > 0 ){
            for (OverviewModel character:characterList) {
                if(character.getK2110() == null || character.getK2111() == null) continue;
                //根据被测参数 获取 测量值
                List<Double> values = this.wertevarRepository.getValueByProcessAndMachine(filters,machineIds,partIds,nestIds, startTime, endTime);
                if(values != null && values.size() > 0){
                    Double avg = 0.00D;
                    for (Double d:values) {
                        avg = avg+d;
                    }
                    avg = avg/values.size();
                    Double down = character.getK2110();
                    Double up = character.getK2111();
                    Double sigma = sigmaUtil.getSigma(values,avg);
                    Double T = up - down;

                    //cp
                    Double  cp= MathUtil.divDouble(T,6*sigma);
                    cp = DoubleUtils.retain2(cp);
                    Double cpu = MathUtil.divDouble((up - avg) , 3*sigma);
                    cpu = DoubleUtils.retain2(cpu);
                    Double cpl = MathUtil.divDouble((avg - down),3*sigma);
                    cpl = DoubleUtils.retain2(cpl);
                    //cpk
                    Double cpk = Math.min(cpu,cpl);
                    // 判断状态  产品是否合格
                    if(cp >= character.getCpTarget()
                            && cpk >= character.getCpkTarget()){
                        if(values != null && values.size() <= 40 ){
                            group.setHasQualified(group.getHasQualified()+1);
                        }else{
                            group.setQualified(group.getQualified()+1);
                        }
                    }else{
                        group.setDisqualification(group.getDisqualification()+1);
                    }
                }else{
                    group.setHasQualified(0);
                    group.setQualified(0);
                    group.setDisqualification(0);
                    group.setCount(0);
                }
            }
//            group.setQualifiedRate(DoubleUtils.retainPercent2 ((double) (group.getQualified()/characterList.size())));
//            group.setHasQualifiedRate(DoubleUtils.retainPercent2 ((double) (group.getHasQualified()/characterList.size())));
//            group.setDisqualificationRate(DoubleUtils.retainPercent2 ((double) (group.getDisqualification()/characterList.size())));
        }


        return group;
    }


    public List<GroupModel> getAnalyseNest(String filterId, String processIds, String partids, String nestIds, String startTime, String endTime ){
        String filters = null;
        if(filters != null && !filters.equals("")){
            FilterUnit filter = this.filterUnitRepository.findById(filterId).orElse(null);
            if(filter != null){
                filters = filter.getImportance();
            }
        }

        List<TreeModel> treeList = abilityLineService.getHierarchySelect();
        Set<Integer> process = new HashSet<>();
        Set<Integer> machine = new HashSet<>();
        if(treeList != null){
            for (TreeModel tree:treeList) {
                process.add(tree.getId());
                if(tree != null && tree.getChildren() != null && tree.getChildren().size() > 0 ){
                    for (TreeModel twoTree:tree.getChildren()) {
                        machine.add(twoTree.getId());
                    }
                }
            }
        }

        //工序
        if(StringUtils.isNotBlank(processIds)){
            process = StringCastSet(processIds);
        }
        List<GroupModel> groupList = this.wertevarRepository.getAnalyseNest( filterId, machine,partids ,nestIds, startTime,  endTime );
        List<GroupModel> result = new ArrayList<>();
        for (GroupModel group: groupList) {
            GroupModel resultGroup  = selectGroupList(group,filters,machine,StringCastSet(partids),nestIds,startTime,endTime);
            result.add(resultGroup);
        }
        return result;
    }


    /**
     * "1,2,3"  String 转 集合
     * @param ids
     * @return
     */
    public Set<Integer> StringCastSet(String ids) {
        Set<Integer> set = null;
        if (StringUtils.isNotBlank(ids)) {
            set = new HashSet<>();
            List<Integer> setList = new ArrayList<>();
            for (String s : ids.split(",")) {
                setList.add(Integer.parseInt(s));
            }

            set.addAll(setList);
        }
        return set;
    }


    public Set<Integer> StringCastMachine(String ids,List<TreeModel> treeList) {
        Set<Integer> set = null;
        if (StringUtils.isNotBlank(ids)) {
            set = new HashSet<>();
            List<Integer> setList = new ArrayList<>();
            for (String s : ids.split(",")) {
                setList.add(Integer.parseInt(s));
            }

            set.addAll(setList);
        }
        Set<Integer> machine = new HashSet<>();
        if (treeList != null) {
            for (TreeModel tree : treeList) {
                if (set == null || set.contains(tree.getId())) {
                    if (tree != null && tree.getChildren() != null && tree.getChildren().size() > 0) {
                        for (TreeModel twoTree : tree.getChildren()) {
                            machine.add(twoTree.getId());
                        }
                    }
                }
            }
        }
        return machine;
    }
}
